package com.kk.miaosha.service.impl;

import cn.hutool.http.HttpStatus;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kk.miaosha.Vo.AdminVo;
import com.kk.miaosha.entity.User;
import com.kk.miaosha.entity.UserRole;
import com.kk.miaosha.exception.CustomException;
import com.kk.miaosha.mapper.UserMapper;
import com.kk.miaosha.mapper.UserRoleMapper;
import com.kk.miaosha.securityEntity.UserDetail;
import com.kk.miaosha.securityEntity.UserDetailService;
import com.kk.miaosha.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kk.miaosha.utils.JwtTokenUtil;
import com.kk.miaosha.utils.RedisKeyUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 用户信息表 服务实现类
 * </p>
 *
 * @author kk
 * @since 2020-09-18
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private AuthenticationManager authenticationManager;
    @Resource
    private UserDetailService userDetailService;
    @Resource
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserRoleMapper userRoleMapper;

    @Override
    public User findOne(String username) {
        return baseMapper.selectOne(new QueryWrapper<User>().eq("user_name",username));
    }

    @Override
    public  Map<String ,Object> login(String username, String password) {
        //校验
        try {
            UsernamePasswordAuthenticationToken upToken =
                    new UsernamePasswordAuthenticationToken(username, password);
            //查询数据库验证账号密码
            //Manager会选择对应的provider来进行认证，并从数据库中查询以及进入loadUserByUsername（第一次）
            Authentication authentication = authenticationManager.authenticate(upToken);
            //放入SecurityContextHolder中的ThreadLocal存储
            SecurityContextHolder.getContext().setAuthentication(authentication);

        }catch (AuthenticationException e){
            throw new CustomException(HttpStatus.HTTP_BAD_REQUEST,"用户名或者密码不正确");
        }
        //进入loadUserByUsername(第二次)
        UserDetail userDetail = (UserDetail)userDetailService.loadUserByUsername(username);
        Map<String ,Object> map=new HashMap<>();
        if (userDetail.getUser().getIsHidden()==0){
            //用户被冻结
            SecurityContextHolder.clearContext();
            throw new CustomException(HttpStatus.HTTP_BAD_REQUEST,"该账号已被冻结，请联系管理员");
        }
        map.put("userInfo",userDetail.getUser());
        map.put("token",jwtTokenUtil.generateToken(userDetail));
        return map;
    }

    @Override
    @Transactional
    public Map<String, Object> register(User user) {
        //查询是否是重复注册用户
        User checkUser = userMapper.selectOne(new QueryWrapper<User>().eq("user_name", user.getUserName()));
        //用户名校验
        if (checkUser!=null) {
            throw new CustomException(HttpStatus.HTTP_BAD_REQUEST,"该账号已注册!");
        }

        user.setPhone("123123123");
        user.setEmail("100120123@qq.com");
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        userMapper.insert(user);
        UserDetail userDetail = (UserDetail)userDetailService.loadUserByUsername(user.getUserName());
        Map<String ,Object> map=new HashMap<>();
        map.put("userInfo",userDetail.getUser());
        map.put("token",jwtTokenUtil.generateToken(userDetail));
        //赋予初始角色
        UserRole userRole=new UserRole();
        userRole.setUserId(user.getId());
        userRole.setRoleId(1);
        userRoleMapper.insert(userRole);
        return map;
    }

    @Override
    @Transactional
    public void delUserCache(UserDetail userDetail) {
        Integer id = userDetail.getUser().getId();
        User user = userMapper.selectById(id);
        if (user!=null){
            String userKey = RedisKeyUtil.getUserKey(user.getUserName());
            redisTemplate.delete(userKey);
            String userMenuKey = RedisKeyUtil.getUserMenuKey(user.getUserName());
            redisTemplate.delete(userMenuKey);
        }
    }

    @Override
    public List<AdminVo> getAdminVoList(List<User> list) {
        List<AdminVo> admins=new ArrayList<>();
        for (User user:list){
            admins.add(userMapper.getAdminVoList(user.getId()));
        }
        return admins;
    }

    @Override
    public void updateAdmin(User user) {
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        baseMapper.updateById(user);
    }


    //刷新令牌
    public String refreshToken(String oldToken){
        if(!jwtTokenUtil.isTokenExpired(oldToken)){
            return jwtTokenUtil.refreshToken(oldToken);
        }
        return null;
    }
}
